{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#################### import all libraries and initializations ############\n",
    "\n",
    "import sys\n",
    "import numpy as np \n",
    "import os\n",
    "import time\n",
    "import math\n",
    "from PIL import Image\n",
    "import matplotlib.pylab as plt\n",
    "import cv2\n",
    "from datetime import datetime\n",
    "from pynq import Xlnk\n",
    "from pynq import Overlay\n",
    "from preprocessing import *\n",
    "import struct\n",
    "\n",
    "team = 'iSmart2'\n",
    "agent = Agent(team)\n",
    "interval_time = 0\n",
    "\n",
    "xlnk = Xlnk()\n",
    "xlnk.xlnk_reset()\n",
    "\n",
    "img = xlnk.cma_array(shape=(3,162,322), dtype=np.uint8)\n",
    "\n",
    "conv_weight_1x1_all = xlnk.cma_array(shape=(1181, 16, 16), dtype=np.uint16)\n",
    "conv_weight_3x3_all = xlnk.cma_array(shape=(46, 16, 3, 3), dtype=np.uint16)\n",
    "bias_all = xlnk.cma_array(shape=(123, 16), dtype=np.uint16)\n",
    "DDR_pool_3_out = xlnk.cma_array(shape=(48, 82, 162), dtype=np.uint16)\n",
    "DDR_pool_6_out = xlnk.cma_array(shape=(96, 42, 82), dtype=np.uint16)\n",
    "DDR_buf = xlnk.cma_array(shape=(36, 16, 22, 42), dtype=np.uint16)\n",
    "predict_box = xlnk.cma_array(shape=(5,), dtype=np.float32)\n",
    "\n",
    "print(\"Allocating memory done\")\n",
    "\n",
    "img_path = '/home/xilinx/jupyter_notebooks/dac_2018/images/'\n",
    "coord_path = '/home/xilinx/jupyter_notebooks/dac_2018/result/coordinate/iSmart2/'\n",
    "\n",
    "tbatch = 0\n",
    "total_num_img = len(agent.img_list)\n",
    "#print(total_num_img)\n",
    "result = list()\n",
    "agent.reset_batch_count()        \n",
    "        \n",
    "blank = Image.new('RGB', (322, 162), (127, 127, 127))\n",
    "\n",
    "# load parameters from SD card to DDR\n",
    "params = np.fromfile(\"iSmart2.bin\", dtype=np.uint16)\n",
    "idx = 0\n",
    "\n",
    "np.copyto(conv_weight_1x1_all, params[idx:idx+conv_weight_1x1_all.size].reshape(conv_weight_1x1_all.shape))\n",
    "idx += conv_weight_1x1_all.size\n",
    "\n",
    "np.copyto(conv_weight_3x3_all, params[idx:idx+conv_weight_3x3_all.size].reshape(conv_weight_3x3_all.shape))\n",
    "idx += conv_weight_3x3_all.size\n",
    "\n",
    "np.copyto(bias_all, params[idx:idx+bias_all.size].reshape(bias_all.shape))\n",
    "\n",
    "print(\"Parameters loading done\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "################### download the overlay #####################\n",
    "overlay = Overlay('/home/xilinx/jupyter_notebooks/dac_2018/overlay/iSmart2/iSmart2.bit')\n",
    "\n",
    "print(\"iSmart2.bit loaded\")\n",
    "myIP = overlay.mobilenet_0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "################## download weights and image resizing and processing\n",
    "\n",
    "myIP.write(0x10, img.physical_address)\n",
    "\n",
    "myIP.write(0x18, conv_weight_1x1_all.physical_address)\n",
    "myIP.write(0x20, conv_weight_3x3_all.physical_address)\n",
    "myIP.write(0x28, bias_all.physical_address)\n",
    "\n",
    "myIP.write(0x30, DDR_pool_3_out.physical_address)\n",
    "myIP.write(0x38, DDR_pool_6_out.physical_address)\n",
    "\n",
    "myIP.write(0x40, DDR_buf.physical_address)\n",
    "myIP.write(0x48, predict_box.physical_address)\n",
    "\n",
    "\n",
    "\n",
    "def process_image(currPic):\n",
    "    #print(img_path + currPic)\n",
    "    image = Image.open(img_path + currPic).convert('RGB')\n",
    "    image = image.resize((320, 160))\n",
    "    blank.paste(image, (1, 1))\n",
    "    image = np.transpose(blank, (2, 0, 1))\n",
    "    np.copyto(img, np.array(image))\n",
    "    \n",
    "\n",
    "first_image = True\n",
    "boxes = []\n",
    "names = []\n",
    "\n",
    "################### Start to detect ################\n",
    "start = time.time()\n",
    "for batch in get_image_batch():\n",
    "    for currPic in batch:\n",
    "        #print(currPic)\n",
    "        names.append(currPic)\n",
    "\n",
    "        if first_image:\n",
    "            image = Image.open(img_path + currPic).convert('RGB')\n",
    "            image = image.resize((320, 160))\n",
    "            blank.paste(image, (1, 1))\n",
    "            image = np.transpose(blank, (2, 0, 1))\n",
    "            np.copyto(img, np.array(image))\n",
    "\n",
    "            first_image = False\n",
    "            continue\n",
    "            \n",
    "        if not first_image:\n",
    "            myIP.write(0x00, 1)\n",
    "            time.sleep(0.07)\n",
    "            image = Image.open(img_path + currPic).convert('RGB')\n",
    "            image = image.resize((320, 160))\n",
    "            blank.paste(image, (1, 1))\n",
    "            image = np.transpose(blank, (2, 0, 1))\n",
    "            np.copyto(img, np.array(image))\n",
    "        \n",
    "        isready = myIP.read(0x00)\n",
    "        while( isready == 1 ):\n",
    "            isready = myIP.read(0x00)\n",
    "            \n",
    "        predict_box[0] = predict_box[0] / 40;\n",
    "        predict_box[1] = predict_box[1] / 20;\n",
    "        predict_box[2] = predict_box[2] / 40;\n",
    "        predict_box[3] = predict_box[3] / 20;\n",
    "        #print(predict_box)\n",
    "        x1 = int(round((predict_box[0] - predict_box[2]/2.0) * 640))\n",
    "        y1 = int(round((predict_box[1] - predict_box[3]/2.0) * 360))\n",
    "        x2 = int(round((predict_box[0] + predict_box[2]/2.0) * 640))\n",
    "        y2 = int(round((predict_box[1] + predict_box[3]/2.0) * 360))\n",
    "        boxes.append([x1, x2, y1, y2])\n",
    "        #print([x1, x2, y1, y2])\n",
    "        \n",
    "\n",
    "#collect result for last image\n",
    "myIP.write(0x00, 1)\n",
    "isready = myIP.read(0x00)\n",
    "while( isready == 1 ):\n",
    "    isready = myIP.read(0x00)   \n",
    "    \n",
    "predict_box[0] = predict_box[0] / 40;\n",
    "predict_box[1] = predict_box[1] / 20;\n",
    "predict_box[2] = predict_box[2] / 40;\n",
    "predict_box[3] = predict_box[3] / 20;\n",
    "#print(predict_box)\n",
    "x1 = int(round((predict_box[0] - predict_box[2]/2.0) * 640))\n",
    "y1 = int(round((predict_box[1] - predict_box[3]/2.0) * 360))\n",
    "x2 = int(round((predict_box[0] + predict_box[2]/2.0) * 640))\n",
    "y2 = int(round((predict_box[1] + predict_box[3]/2.0) * 360))\n",
    "boxes.append([x1, x2, y1, y2])\n",
    "        \n",
    "        \n",
    "end = time.time()\n",
    "tbatch = end - start\n",
    "\n",
    "        \n",
    "print(\"All computation done\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "################ record the results and write to XML\n",
    "f_out = open(coord_path + '/iSmart2.txt', 'w')\n",
    "#f_out = open('./iSmart2.txt', 'w')\n",
    "cnt = 0\n",
    "for box in boxes:\n",
    "    x1 = box[0]\n",
    "    x2 = box[1]\n",
    "    y1 = box[2]\n",
    "    y2 = box[3]\n",
    "    coord = str(x1) + ' ' + str(x2) + ' ' + str(y1) + ' ' + str(y2)\n",
    "    \n",
    "    name = names[cnt]\n",
    "    cnt = cnt + 1\n",
    "    f_out.write(name + '\\n')\n",
    "    f_out.write(coord + '\\n')\n",
    "        \n",
    "f_out.close()\n",
    "print(\"\\nAll results stored in iSmart2_out.txt\")\n",
    "\n",
    "agent.save_results_xml(boxes)\n",
    "agent.write(tbatch, total_num_img, team)\n",
    "\n",
    "print(\"XML and time results written successfully.\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "############## clean up #############\n",
    "xlnk.xlnk_reset()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
